using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

/// <summary>
/// 子弹池，使用抽象层重构
/// 支持多种子弹类型，每种类型使用独立的对象池
/// </summary>
public class BulletPool : MonoBehaviour
{
    public static BulletPool Instance { get; private set; }
    
    [SerializeField] private int initialPoolSize = 20;
    [SerializeField] private int maxPoolSize = 100;

    // 为每种子弹预制体维护独立的对象池
    private Dictionary<GameObject, IPool<GameObject>> m_Pools = new Dictionary<GameObject, IPool<GameObject>>();

    private void Awake()
    {
        Instance = this;
    }

    /// <summary>
    /// 获取或创建指定预制体的对象池
    /// </summary>
    private IPool<GameObject> GetOrCreatePool(GameObject prefab)
    {
        if (prefab == null)
        {
            Logger.LogError("BulletPool", "子弹预制体为空！");
            return null;
        }

        // 如果已存在该预制体的对象池，直接返回
        if (m_Pools.TryGetValue(prefab, out var existingPool))
        {
            return existingPool;
        }

        // 创建新的对象池
        var poolManager = PoolManagerHelper.GetOrCreatePoolManager();
        if (poolManager == null)
        {
            Logger.LogError("BulletPool", "无法获取或创建 PoolManager！");
            return null;
        }

        var newPool = poolManager.CreateGameObjectPool(
            prefab,
            initialPoolSize,
            maxPoolSize,
            transform
        );

        m_Pools[prefab] = newPool;
        Logger.Log("BulletPool", $"为子弹预制体 {prefab.name} 创建了新的对象池");
        
        return newPool;
    }

    /// <summary>
    /// 获取子弹对象（使用 BulletData 中的 Prefab）
    /// </summary>
    public Bullet GetBullet(BulletData bulletData)
    {
        if (bulletData == null || bulletData.Prefab == null)
        {
            Logger.LogError("BulletPool", "BulletData 或 Prefab 为空！");
            return null;
        }

        // 获取或创建对应预制体的对象池
        var pool = GetOrCreatePool(bulletData.Prefab);
        if (pool == null)
        {
            return null;
        }

        var bulletObj = pool.Get();
        if (bulletObj != null)
        {
            var bullet = bulletObj.GetComponent<Bullet>();
            if (bullet == null)
            {
                Logger.LogError("BulletPool", $"子弹预制体 {bulletData.Prefab.name} 没有 Bullet 组件！");
                pool.Return(bulletObj);
                return null;
            }
            bullet.gameObject.SetActive(true);
            return bullet;
        }
        return null;
    }

    /// <summary>
    /// 获取子弹对象（兼容旧接口，使用 BulletType）
    /// </summary>
    [System.Obsolete("请使用 GetBullet(BulletData) 方法，该方法会根据 BulletData.Prefab 获取正确的子弹预制体")]
    public Bullet GetBullet(BulletType type)
    {
        Logger.LogWarning("BulletPool", "使用了过时的 GetBullet(BulletType) 方法，请使用 GetBullet(BulletData) 方法");
        // 降级处理：尝试从已存在的池中获取（不推荐）
        foreach (var pool in m_Pools.Values)
        {
            var bulletObj = pool.Get();
            if (bulletObj != null)
            {
                var bullet = bulletObj.GetComponent<Bullet>();
                if (bullet != null)
                {
                    bullet.gameObject.SetActive(true);
                    return bullet;
                }
                pool.Return(bulletObj);
            }
        }
        return null;
    }

    /// <summary>
    /// 归还子弹对象
    /// </summary>
    public void ReturnBullet(Bullet bullet)
    {
        if (bullet == null) return;

        // 停止DOTween动画
        bullet.transform.DOKill();

        // 找到对应的对象池并归还
        // 通过遍历所有池来查找，使用名称匹配
        string bulletName = bullet.gameObject.name.Replace("(Clone)", "");
        foreach (var kvp in m_Pools)
        {
            string prefabName = kvp.Key.name;
            // 检查对象的名称是否匹配预制体名称
            if (bulletName == prefabName || bulletName.StartsWith(prefabName))
            {
                kvp.Value.Return(bullet.gameObject);
                return;
            }
        }

        // 如果找不到对应的池，记录警告并直接销毁
        Logger.LogWarning("BulletPool", $"无法找到子弹 {bullet.name} 对应的对象池，直接销毁");
        Destroy(bullet.gameObject);
    }

    /// <summary>
    /// 获取池状态信息
    /// </summary>
    public void LogPoolStatus()
    {
        Logger.Log("BulletPool", $"总共有 {m_Pools.Count} 个子弹对象池");
        foreach (var kvp in m_Pools)
        {
            var pool = kvp.Value;
            Logger.Log("BulletPool", $"  {kvp.Key.name}: Total={pool.Count}, Active={pool.ActiveCount}");
        }
    }

    private void OnDestroy()
    {
        foreach (var pool in m_Pools.Values)
        {
            pool?.Clear();
        }
        m_Pools.Clear();
    }
}